package com.usefullc.system.configuration;

import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.core.toolkit.PluginUtils;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.DynamicTableNameInnerInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.InnerInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import com.usefullc.common.context.ContextManager;
import com.usefullc.common.user.OnlineUser;
import com.usefullc.common.user.OnlineUserManager;
import com.usefullc.system.service.component.ITenantComponent;
import org.apache.commons.collections.CollectionUtils;
import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.executor.statement.StatementHandler;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.session.ResultHandler;
import org.apache.ibatis.session.RowBounds;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Lazy;

import java.sql.SQLException;
import java.util.List;

/**
 * @doc see https://baomidou.com/pages/2976a3/#innerinterceptor
 */
@Configuration
public class MyBatisPlusConfig {

    @Lazy
    @Autowired
    private ITenantComponent tenantComponent;



//    public  PaginationInnerInterceptor paginationInnerInterceptor(){
//        return new PaginationInnerInterceptor();
//    }

    private String replaceTableName(String tableName){
        if(tenantComponent == null){
            return tableName;
        }
        //获取租户id
        Long tenantId = ContextManager.getTenantId();
        if(tenantId == null){
            return tableName;
        }

        //表名是否是应用中的表
        List<String> tenantTableNames = tenantComponent.getTenantTableNames();
        boolean hasEscape = false;
        if(tableName.startsWith("`")){
            hasEscape = true;
            tableName = tableName.substring(1,tableName.length()-1);
        }
        if (CollectionUtils.isEmpty(tenantTableNames) || !tenantTableNames.contains(tableName)) {
            return tableName;
        }
        tableName = tableName + "_"+tenantId;
        if(hasEscape){
            tableName = "`"+tableName+"`";
        }
        return tableName;
    }

    private boolean isTenantTable(String tableName){
        if(tenantComponent == null){
            return false;
        }
        //获取租户id
        Long tenantId = ContextManager.getTenantId();
        if(tenantId == null){
            return false;
        }

        //表名是否是应用中的表
        List<String> tenantTableNames = tenantComponent.getTenantTableNames();
        if (CollectionUtils.isEmpty(tenantTableNames) || !tenantTableNames.contains(tableName)) {
            return false;
        }
        return true;
    }


    @Bean
    public MybatisPlusInterceptor dyNamePlusInterceptor(){
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();

        PaginationInnerInterceptor innerInterceptor = new PaginationInnerInterceptor(DbType.MYSQL);
//        innerInterceptor.setMaxLimit(500L);
        interceptor.addInnerInterceptor(innerInterceptor);


        DynamicTableNameInnerInterceptor dynamicTableNameInnerInterceptor = new DynamicTableNameInnerInterceptor();
        dynamicTableNameInnerInterceptor.setTableNameHandler((sql, tableName) -> replaceTableName(tableName));
        interceptor.addInnerInterceptor(dynamicTableNameInnerInterceptor);

        InnerInterceptor newInterceptor = new InnerInterceptor() {

            @Override
            public void beforeGetBoundSql(StatementHandler sh) {
//                BoundSql boundSql = sh.getBoundSql();
//                PluginUtils.MPBoundSql mpBoundSql = PluginUtils.mpBoundSql(boundSql);
//                String sql = boundSql.getSql();
//                String newSql = sql;
//                String[] terms = sql.split("\\s+");
//                for (int i = 1; i < terms.length; i++) {
//                    String tableName = terms[i].trim();
//                    String previousTerm = terms[i-1].trim();
//                    if(previousTerm.equalsIgnoreCase("into") ||
//                            previousTerm.equalsIgnoreCase("from") ||
//                            previousTerm.equalsIgnoreCase("JOIN")){
//                        if (!isTenantTable(tableName)) {
//                            continue;
//                        }
//                        String replaceTableName = replaceTableName(tableName);
//                        if(replaceTableName.equals(tableName)){
//                            continue;
//                        }
//                        newSql = newSql.replace(tableName,replaceTableName);
//
//                    }
//                }
//                mpBoundSql.sql(newSql);
            }

            @Override
            public void beforeQuery(Executor executor, MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) throws SQLException {
//                BoundSql boundSql1 = ms.getBoundSql(parameter);
                if(tenantComponent == null){
                    return;
                }
                //获取租户id
                Long tenantId = ContextManager.getTenantId();
                if(tenantId == null){
                    return;
                }
                String sql = boundSql.getSql();
                String newSql = sql;
                String[] terms = sql.split("\\s+");
                for (int i = 1; i < terms.length; i++) {
                    String tableName = terms[i].trim();
                    String previousTerm = terms[i-1].trim();
                    if(previousTerm.equalsIgnoreCase("into") ||
                            previousTerm.equalsIgnoreCase("from") ||
                            previousTerm.equalsIgnoreCase("JOIN")){
                        if (!isTenantTable(tableName)) {
                            continue;
                        }
                        String replaceTableName = replaceTableName(tableName);
                        if(replaceTableName.equals(tableName)){
                            continue;
                        }
                        newSql = newSql.replace(tableName,replaceTableName);

                    }
                }
//                if(newSql.indexOf("fire_device_audit_record_0") == -1){
//                    newSql = newSql.replaceAll("fire_device_audit_record","fire_device_audit_record_0");
//                }
                PluginUtils.MPBoundSql mpBoundSql = PluginUtils.mpBoundSql(boundSql);
                mpBoundSql.sql(newSql);
            }
        };
        interceptor.addInnerInterceptor(newInterceptor);
        return interceptor;
    }
}
